<?php

/*
 *  This file is part of Urd.
 *
 *  Urd is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *  Urd is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. See the file "COPYING". If it does not
 *  exist, see <http://www.gnu.org/licenses/>.
 *
 * $LastChangedDate: 2008-07-18 19:15:03 +0200 (Fri, 18 Jul 2008) $
 * $Rev: 1304 $
 * $Author: gavinspearhead $
 * $Id: urd_log.php 1304 2008-07-18 17:15:03Z gavinspearhead $
 */

if (!defined('ORIGINAL_PAGE')) die('This file cannot be accessed directly.');


$pathul = realpath(dirname(__FILE__));


require_once "$pathul/defines.php";
require_once "$pathul/../config.php";


openlog($process_name, LOG_ODELAY, LOG_LOCAL7);


$hostname = php_uname('n');

function trace_str($trace)
{
	$str = '';
	foreach ($trace as $k => $line){
		if ($k == 0) continue;
		$function = $line['function'];
		$linenr = $line['line'];
		$file = $line['file'];
		$args = $line['args'];
		$args_str = '';
		foreach($args as $a) 
			$args_str .= gettype($a) . ' ,';
		$args_str=rtrim($args_str, ', ');

		$str .= "#$k $file($linenr) $function($args_str)\n";
	}
	return $str;
}


function my_assert_handler($file, $line, $code)
{
	write_log("Assert failed: $file ($line)", LOG_WARNING);
	write_log(trace_str(debug_backtrace()), LOG_INFO);
}


function set_assert($on)
{
	if ($on === TRUE) {
		// Active assert and make it quiet
		assert_options(ASSERT_ACTIVE, 1);
		assert_options(ASSERT_WARNING, 0);
		assert_options(ASSERT_BAIL, 0);
		assert_options(ASSERT_QUIET_EVAL, 1);
		assert_options(ASSERT_CALLBACK, 'my_assert_handler');
	} else {
		// disable assert and make it quiet
		assert_options(ASSERT_ACTIVE, 0);
		assert_options(ASSERT_WARNING, 0);
		assert_options(ASSERT_BAIL, 0);
		assert_options(ASSERT_QUIET_EVAL, 1);
		assert_options(ASSERT_CALLBACK, NULL);
	}
}


function debug_match($current_level, $presented_level)
{
	return ($current_level & $presented_level) != 0;
}


function socket_error_handler($die=FALSE)
{
	$errno = socket_last_error();
	if ($errno == 0) // no error
		return;
	$errstr = socket_strerror($errno);
	socket_clear_error();
	if ($die) {
		write_log("Error: $errstr ($errno)", LOG_ERR);
		exit(SOCKET_FAILURE);
	} elseif ($errno == 104) {
		// Default connection reset by peer error:
		write_log("Error: $errstr ($errno)", LOG_DEBUG);
	} else {
		write_log("Error: $errstr ($errno)", LOG_INFO);
	}
}


function echo_debug_trace(exception $e, $dbg_lvl)
{
	echo_debug($e->getTraceAsString(), $dbg_lvl);
}


function echo_debug_function($dbg_lvl, $function)
{
	global $config;
	if (debug_match($dbg_lvl, $config['urdd_debug_level'])) {
		$pid = posix_getpid();
		$mmu = memory_get_usage (TRUE);
		$mmpu = memory_get_peak_usage (TRUE);
		$msg = "fn:{$function}() pid:$pid ($mmu $mmpu)";
		echo_debug($msg, $dbg_lvl);
	}
}


function echo_debug_var_file($file, $var)
{
	ob_start();
	var_dump($var);
	$a = ob_get_contents();
	ob_end_clean();
	file_put_contents($file, $a, FILE_APPEND);
}


function echo_debug_var($var, $dbg_lvl)
{
	ob_start();
	var_dump($var);
	$a = ob_get_contents();
	ob_end_clean();
	echo_debug($a, $dbg_lvl);
}


function echo_debug($msg, $dbg_lvl)
{
	global $config;

	if (debug_match($dbg_lvl, $config['urdd_debug_level'])) {
		$lines = explode ("\n", $msg);
		foreach ($lines as $ln)
			if (trim($ln) !== '')
				write_log($ln, LOG_DEBUG);
	}
}

$logging_enabled = TRUE;

function enable_log()
{
	global $logging_enabled;
	$logging_enabled = TRUE;
}


function disable_log()
{
	global $logging_enabled;
	$logging_enabled = FALSE;
}


function open_logfile($filename, $proc_name)
{
    global $LOGFILE, $process_name;
    $process_name = $proc_name;
	$f = @fopen($filename, 'a');
	if ($f === FALSE) {
		echo "Error: cannot open logfile ($filename) for appending\n";
		exit(CONFIG_ERROR);
	}
	$LOGFILE = $f;
	write_log("Opening log file: $filename", LOG_INFO);

	// Also try a chmod:
	$rv = @chmod($filename, 0660); // TODO fix logfiles properly
	if ($rv === FALSE)
		write_log('Warning: cannot set permissions on logfile', LOG_WARNING);
}


function reopen_logfile($filename, $proc_name)
{
	global $LOGFILE;
	fclose($LOGFILE);
	open_logfile($filename, $proc_name);
}


function write_log($message, $priority=LOG_INFO) // do not add a newline; this fn prints one line if you want to write multi line msgs do more write_logs
{
	global $LOGFILE, $config, $logging_enabled, $log_str, $hostname, $process_name;
	if ($logging_enabled === FALSE || $priority > $config['urdd_min_loglevel']) 
		return;
	$log_options = get_logoption($config['urdd_log']);
	$date = date('M d H:i:s');
	$lines = explode("\n", $message);
	foreach($lines as $msg) {
		foreach($log_options as $opt) {
			switch($opt) {
			case 'file' :
				if (!is_resource($LOGFILE)) 
                    open_logfile($config['log_file'], $process_name);

				fwrite($LOGFILE, $date . ' ' . $hostname . " $process_name: " .  $log_str[$priority] . ' ' . $msg . "\n");
				fflush($LOGFILE);
				break;
			case 'stderr':
				if (($config['urdd_daemonise'] === FALSE) && ((defined('ORIGINAL_PAGE') === FALSE) || ORIGINAL_PAGE === 'URDD')) {
					fwrite(STDERR, $date . ' ' .  $hostname . " $process_name: " . $log_str[$priority] . ' ' . $msg . "\n");
					fflush(STDERR);
				}
				break;
            case 'syslog':
				syslog($priority, $log_str[$priority] . ' ' .$msg);
				break;
			default:
				echo "Unknown log option\n";
				exit(CONFIG_ERROR);
				break;
			}
		}
	}
}


$urd_log_opt = NULL;
function get_logoption($log)
{
	global $urd_log_opt;
	if ($urd_log_opt === NULL) 
		$urd_log_opt = preg_split('/[\s]*\|[\s]*/', $log); // log options are separated by a | and optional spaces
		
	return $urd_log_opt;
}


?>
